package com.wq.app.painter.widget.draw;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;

import com.wq.app.painter.data.Stroke;
import com.wq.app.painter.data.Stroke.StrokePoint;
import com.wq.app.painter.widget.draw.log.LogPrinter;

import java.util.ArrayList;


public class StrokeDrawer {
    private Path path;
    private Paint paint;
    private int pointIndex;
    private Stroke currStroke;
    private StrokePoint prevPoint;
    /**
     * 笔画区域，据此判断是否在视图区域，以决定是否予以显示
     */
    private Rect strokeArea;

    public StrokeDrawer(Stroke stroke) {
        initGesturePaint();
        this.currStroke = stroke;
    }

    public void onDraw(Canvas canvas) {
        if (null != currStroke) {
            drawStroke(canvas, currStroke);
        }
    }

    public Rect getStrokeArea() {
        return strokeArea.isEmpty() ? currStroke.getArea() : strokeArea;
    }

    private void drawStroke(Canvas canvas, Stroke stroke) {
        LogPrinter.log("drawStroke size: " + stroke.getPointCount());
        paint.setStrokeWidth(stroke.getWith());
        paint.setColor(stroke.getColor());

        //说明笔画没有改变（未新增任何点）
        if (prevPoint == stroke.getLastPoint()) {
            canvas.drawPath(path, paint);
        } else {
            drawPoints(canvas, stroke);
        }
    }

    private void drawPoints(Canvas canvas, Stroke stroke) {
        StrokePoint point;

        //如果是上一次显示的笔画，为了提高效率，不重新绘制，重用此前的绘制轨迹，绘制新增点
        int index = pointIndex;
        ArrayList<StrokePoint> points = stroke.getPoints();
        final int size = points.size();
        for (; index < size; index++) {
            point = points.get(index);

            if (0 == index) {
                drawStartPoint(canvas, point);
//            } else if (size - 1 == index) {
//                drawEndPoint(canvas, point);
            } else {
                drawMovePoint(canvas, point);
            }

            pointIndex = index;
            strokeArea.union(point.getX(), point.getY());
        }
    }

    private void drawStartPoint(Canvas canvas, StrokePoint point) {
        path.reset();
        path.moveTo(point.getX(), point.getY());
        canvas.drawPath(path, paint);

        prevPoint = point;
    }

    private void drawMovePoint(Canvas canvas, StrokePoint point) {
        path.quadTo(prevPoint.getX(), prevPoint.getY(), (prevPoint.getX() + point.getX()) / 2f, (prevPoint.getY() + point.getY()) / 2f);
        canvas.drawPath(path, paint);
        prevPoint = point;
    }

    private void drawEndPoint(Canvas canvas, StrokePoint point) {
        path.lineTo(point.getX(), point.getY());
        canvas.drawPath(path, paint);
        prevPoint = point;
    }

    private void initGesturePaint() {
        path = new Path();
        strokeArea = new Rect();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
        paint.setDither(true);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
    }
}
